package gui;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Popup;
import javafx.stage.Stage;
import logic.Sudoku;
import logic.cell;


public class SudokuMakerGUI extends Application{
	GridPane sudokuDisplay = new GridPane();
	GridPane[][] sudokuBlocks = new GridPane[3][3];
	Stage primaryStage;
	FlowPane options = new FlowPane();
	Sudoku currentPuzzle;
	Button selectedButton = null;
	Button newPuzzLeBTN = new Button("New Puzzle");
	Button printPuzzleBTN = new Button(" Print ");
	Popup winMessage;
	boolean winDisplayed = false;
	
	public final static int SINGLEDISPLAY = 60;
	public final static int FOURDISPLAY = 40;
	public final static int TWODISPLAY = 50;
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Application.launch(args);
	}

	@Override
	public void start(Stage inputPrimaryStage) throws Exception {
		
		primaryStage = inputPrimaryStage;
		
		// remove win popup after click
		primaryStage.addEventFilter(MouseEvent.MOUSE_CLICKED,new EventHandler<MouseEvent>()
		{
			@Override
			public void handle(MouseEvent event) {
				if(winMessage != null)
				{
					if(winDisplayed)						
					{
						winMessage.hide();
						winMessage = null;
						winDisplayed = false;
					}
					else			
					{
						winDisplayed = true;
					}
				}
			}
		});
		BorderPane page = new BorderPane();
		
		currentPuzzle = new Sudoku(Sudoku.EASY);
		displaySudoku(sudokuDisplay,currentPuzzle,SudokuMakerGUI.SINGLEDISPLAY);
		page.setCenter(sudokuDisplay);
        Scene scene = new Scene(page);

        BorderPane footer = new BorderPane();
        footer.setCenter(options);
        
        setUpInputOptions();
        
        page.setBottom(footer);
        
        primaryStage.setTitle("Sudoku");
        primaryStage.setScene(scene);
        primaryStage.show();
		
	}
	
	/**
	 * setup option bar
	 */
	private void setUpInputOptions()
	{
		newPuzzLeBTN.setOnAction(new EventHandler<ActionEvent>() {
			
			@Override
			public void handle(ActionEvent arg0) {
				currentPuzzle = new Sudoku(Sudoku.EASY);
				displaySudoku(sudokuDisplay,currentPuzzle,SudokuMakerGUI.SINGLEDISPLAY);
				
			}
		});
        options.getChildren().add(newPuzzLeBTN);
        
        for(int i = 0; i <= 9;i++)
		{
			Button optionBTN;
			if(i != 0)
			{
				optionBTN = new Button(String.valueOf(i));
				optionBTN.setOnAction(new EventHandler<ActionEvent>() {
					
					@Override
					public void handle(ActionEvent e) {
						Button Inputsource = (Button)e.getSource();
						if(selectedButton != null)		
						{
							selectedButton.setText(Inputsource.getText());
							cell[][] cells = currentPuzzle.getCells();
							String[] xy = selectedButton.getId().split(","); 
							int x = Integer.valueOf(xy[0]);
							int y = Integer.valueOf(xy[1]);
							cell localCell = cells[x][y];
							localCell.setCurrentValue(Integer.valueOf(selectedButton.getText()));
							if(!currentPuzzle.isCellValueAcceptable(localCell))
							{
								selectedButton.setStyle("-fx-text-fill: red;-fx-font-size: 18px;");
								localCell.setCurrentValue(cell.BLANK);
							}
							else
							{
								selectedButton.setStyle("-fx-text-fill: black;-fx-font-size: 18px;");
							}
							if(currentPuzzle.isSolved())
							{
								winMessage = new Popup();
								Label winL = new Label("Winner");
								winL.setStyle("-fx-text-fill: purple;-fx-font-size: 120px;");
								winMessage.getContent().add(winL);
								winMessage.show(primaryStage);
							}
						}
					}
				});
			}
			else
			{
				optionBTN = new Button("");
				optionBTN.setOnAction(new EventHandler<ActionEvent>() {
					
					@Override
					public void handle(ActionEvent e) {
						Button Inputsource = (Button)e.getSource();
						if(selectedButton != null)							
						{
							selectedButton.setText(Inputsource.getText());
							cell[][] cells = currentPuzzle.getCells();
							String[] xy = selectedButton.getId().split(","); 
							int x = Integer.valueOf(xy[0]);
							int y = Integer.valueOf(xy[1]);
							cell localCell = cells[x][y];
							localCell.setCurrentValue(cell.BLANK);
						}
					}
				});
			}
			optionBTN.setStyle("-fx-border-color: lightblue; -fx-border-width: 1px;");
			optionBTN.setPrefSize(40, 40);
			optionBTN.setMinSize(40, 40);
			
			options.setAlignment(Pos.CENTER);
			options.getChildren().add(optionBTN);
		}
        
        options.getChildren().add(printPuzzleBTN);
        printPuzzleBTN.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent arg0) {
				PrintPreveiw.preveiwPrint();			
			}
		});
	}
	
	/**
	 * displays sudoku in grid pane with supplied button size
	 * 
	 * @param sudokuDisplay
	 * @param current
	 * @param buttonSize
	 */
	public void displaySudoku(GridPane sudokuDisplay,Sudoku current,int buttonSize)
	{
		cell[][] sudokuCells = current.getCells();
		for(int x = 0; x < 3;x++)
		{
			for(int y = 0; y < 3;y++)
			{
				GridPane block = new GridPane();
				block.setStyle("-fx-border-color: black; -fx-border-width: 2px;");
				sudokuBlocks[x][y] = block;
				sudokuDisplay.add(block	, x, y);
			}
		}
		
		for(int x = 0; x < 9; x++)
		{
			for(int y =0; y < 9; y++)
			{	
				int currentValue = sudokuCells[x][y].getCurrentValue();
				Button newBTN = new Button();
				newBTN.setStyle("-fx-background-radius: 0;-fx-font-size: 18px;-fx-font-family: 'Arial';");
				newBTN.setPrefSize(buttonSize, buttonSize);
				newBTN.setMinSize(buttonSize, buttonSize);
				if(currentValue == cell.BLANK)
				{
					newBTN.setText("");
					newBTN.setId(x + "," + y);
					newBTN.setOnAction(new EventHandler<ActionEvent>() {
						
						@Override
						public void handle(ActionEvent e) {						
							selectedButton = (Button)e.getSource();
						}
					});
					addToSuddokuPanel(newBTN, x, y);
				}
				else
				{
					newBTN.setText(String.valueOf(currentValue));
					addToSuddokuPanel(newBTN, x, y);
				}
			}
		}
	}
	
	/**
	 * adds buttons to appropriate sub panel
	 * @param btn button object to add
	 * @param x unmodified x value
	 * @param y unmodified y value
	 */
	private void addToSuddokuPanel(Button btn, int x , int y)
	{
		int xBlock = x / 3;
		int yBlock = y / 3;
		int xlocal = x % 3;
		int yLocal = y % 3;
		sudokuBlocks[xBlock][yBlock].add(btn, xlocal, yLocal);
	}

}
